package com.greate.community.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.greate.community.entity.*;
import com.greate.community.entity.dto.PasswordDTO;
import com.greate.community.entity.dto.RealNameDTO;
import com.greate.community.service.*;
import com.greate.community.constant.CommunityConstant;
import com.greate.community.util.CommunityUtil;
import com.greate.community.util.SensitiveFilter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;


/**
 * 用户
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController extends BaseController implements CommunityConstant {

    private final UserService userService;

    private final FollowService followService;

    private final DiscussPostService discussPostService;

    private final CommentService commentService;

    private final SensitiveFilter sensitiveFilter;

    public UserController(UserService userService, FollowService followService, DiscussPostService discussPostService, CommentService commentService, SensitiveFilter sensitiveFilter) {
        this.userService = userService;
        this.followService = followService;
        this.discussPostService = discussPostService;
        this.commentService = commentService;
        this.sensitiveFilter = sensitiveFilter;
    }

    /**
     * 通过ticket获取user
     *
     * @return
     */
    @GetMapping("/get")
    public Result getUserByToken() {
        JSONObject jsonObject = new JSONObject();
        if (getUser() == null) {
            return new Result("fail", "1", "该用户不存在");
        }

        // 用户
        jsonObject.put("user", userService.findUserById(getUser().getId()));
        // 关注数量
        long followeeCount = followService.findFolloweeCount(getUser().getId(), ENTITY_TYPE_USER);
        jsonObject.put("followeeCount", followeeCount);
        // 粉丝数量
        long followerCount = followService.findFollowerCount(ENTITY_TYPE_USER, getUser().getId());
        jsonObject.put("followerCount", followerCount);

        return new Result("success", Result.SUCCESS, jsonObject);
    }

    /**
     * 获取user实名信息
     *
     * @return
     */
    @GetMapping("/realname/get")
    public Result getRealNameUserByToken() {
        if (getUser() == null) {
            return new Result("fail", "1", "实名信息获取失败");
        } else {
            User user = userService.findAllUserById(getUser().getId());
            return new Result("success", Result.SUCCESS, user);
        }
    }

    /**
     * 修改用户名
     *
     * @param newname
     * @return
     */
    @GetMapping("/username")
    public Result updateUsername(@RequestParam String newname) {
        if (StringUtils.isBlank(newname)) {
            return new Result("fail", "1", "用户名不能为空");
        } else if (newname.length() <= 2 || newname.length() > 18) {
            return new Result("fail", "4", "用户名长度为3-18个字符");
        } else if (sensitiveFilter.filter(newname).isHaveSensitive()) {
            return new Result("fail", "5", "名称中含有非法字符");
        }
        int result = userService.updateUsername(getUser().getId(), newname);
        if (result == 2) {
            return new Result("fail", "2", "用户名不能重复");
        } else if (result == 0) {
            return new Result("fail", "3", "用户名修改失败");
        } else {
            return new Result("success", Result.SUCCESS, "用户名修改成功");
        }
    }

    /**
     * 修改用户密码
     *
     * @param passwordDTO
     * @return
     */
    @PostMapping("/password")
    public Result updatePassword(@RequestBody @Validated PasswordDTO passwordDTO) {
        String oldPassword = passwordDTO.getOldPassword();
        String newPassword = passwordDTO.getNewPassword();

        // 验证原密码是否正确
        User user = userService.findUserById(getUser().getId());
        String md5OldPassword = CommunityUtil.md5(oldPassword + user.getSalt());
        if (!user.getPassword().equals(md5OldPassword)) {
            return new Result("fail", "1", "原密码错误");
        }

        // 判断新密码是否合法
        String md5NewPassword = CommunityUtil.md5(newPassword + user.getSalt());
        if (user.getPassword().equals(md5NewPassword)) {
            return new Result("fail", "2", "新密码不能和原密码相同");
        }

        // 修改用户密码
        userService.updatePassword(user.getId(), newPassword);

        return new Result("success", Result.SUCCESS, "修改密码成功");
    }

    /**
     * 获取其它用户信息
     *
     * @param userId 可以进入任意用户的个人主页
     * @return
     */
    @GetMapping("/{userId}")
    public Result getProfilePage(@PathVariable("userId") int userId) {
        JSONObject jsonObject = new JSONObject();
        User user = userService.findUserById(userId);
        if (user == null) {
            return new Result("fail", "1", "该用户不存在");
        }

        // 用户
        jsonObject.put("user", user);
        // 关注数量
        long followeeCount = followService.findFolloweeCount(userId, ENTITY_TYPE_USER);
        jsonObject.put("followeeCount", followeeCount);
        // 粉丝数量
        long followerCount = followService.findFollowerCount(ENTITY_TYPE_USER, userId);
        jsonObject.put("followerCount", followerCount);
        // 当前登录用户是否已关注该用户
        boolean hasFollowed = false;
        if (getUser() != null) {
            hasFollowed = followService.hasFollowed(getUser().getId(), ENTITY_TYPE_USER, userId);
        }
        jsonObject.put("hasFollowed", hasFollowed);

        return new Result("success", Result.SUCCESS, jsonObject);
    }

    /**
     * 进入我的帖子（查询某个用户的帖子列表）
     *
     * @param userId
     * @param page
     * @return
     */
    @GetMapping("/discuss/{userId}")
    public Result getMyDiscussPosts(@PathVariable("userId") int userId, Page page) {
        JSONObject jsonObject = new JSONObject();
        User user = userService.findUserById(userId);
        if (user == null) {
            return new Result("fail", "1", "该用户不存在");
        }
        jsonObject.put("user", user);

        // 该用户的帖子总数
        int rows = discussPostService.findDiscussPostRows(userId);
        jsonObject.put("rows", rows);

//        page.setLimit(5);//前端注入
        page.setPath("/user/discuss/" + userId);
        page.setRows(rows);

        // 分页查询(按照最新查询)
        List<DiscussPost> list = discussPostService.findDiscussPosts(userId, page.getOffset(), page.getLimit(), 0, null, null, 0);
        // 封装帖子和该帖子对应的用户信息
        List<Map<String, Object>> discussPosts = new ArrayList<>();
        if (list != null) {
            list.forEach(discussPost -> {
                Map<String, Object> map = new HashMap<>();
//                map.put("post", post);

                //将discuss_post表中以 , 分隔的pic_url转为json数组返回到前端
                map.put("post", discussPostService.toDiscussPostJsonObject(discussPost));

                discussPosts.add(map);
            });
        }
        JSONArray result = (JSONArray) JSONArray.toJSON(discussPosts);
        page.setResult(result);
        jsonObject.put("discussPosts", page);

        return new Result("success", Result.SUCCESS, jsonObject);
    }

    /**
     * 进入我的评论/回复（查询某个用户的评论/回复列表）
     *
     * @param userId
     * @param page
     * @return
     */
    @GetMapping("/comment/{userId}")
    public Result getMyComments(@PathVariable("userId") int userId, Page page) {
        JSONObject jsonObject = new JSONObject();
        User user = userService.findUserById(userId);
        if (user == null) {
            return new Result("fail", "1", "该用户不存在");
        }
        jsonObject.put("user", user);

        // 该用户的评论/回复总数
        int commentCounts = commentService.findCommentCountByUserId(userId);
        jsonObject.put("commentCounts", commentCounts);

        page.setPath("/user/comment/" + userId);
        page.setRows(commentCounts);

        // 分页查询
        List<Comment> list = commentService.findCommentByUserId(userId, page.getOffset(), page.getLimit());
        // 封装评论和该评论对应的帖子信息
        List<Map<String, Object>> comments = new ArrayList<>();
        if (list != null) {
            list.forEach(comment -> {
                Map<String, Object> map = new HashMap<>();
                // 显示评论/回复对应的文章信息
                map.put("comment", comment);
                if (comment.getRootId() == 0) {
                    // 如果是对帖子的评论
                    DiscussPost post = discussPostService.findDiscussPostById(comment.getPostId());
                    // 将discuss_post表中以 , 分隔的pic_url转为json数组返回到前端
                    map.put("post", discussPostService.toDiscussPostJsonObject(post));
                } else {
                    JSONObject parent = new JSONObject();
                    // 如过是对评论的回复
                    Comment parentComment = commentService.findCommentById(comment.getParentId());
                    parent.put("comment", parentComment);
                    User parentUser = userService.findUserById(parentComment.getParentUserId());
                    parent.put("user", parentUser);
                    map.put("parent", parent);

                    DiscussPost post = discussPostService.findDiscussPostById(comment.getPostId());
                    // 将discuss_post表中以 , 分隔的pic_url转为json数组返回到前端
                    map.put("post", discussPostService.toDiscussPostJsonObject(post));
                }

                comments.add(map);
            });
        }

        JSONArray result = (JSONArray) JSONArray.toJSON(comments);
        page.setResult(result);
        jsonObject.put("comments", page);

        return new Result("success", Result.SUCCESS, jsonObject);
    }

    /**
     * 更新用户实名信息
     *
     * @param realNameDTO
     * @return
     */
    @PostMapping("/realname/update")
    public Result updateRealNameInfo(@RequestBody @Validated RealNameDTO realNameDTO) {
        // 已实名认证通过，则无法更新实名信息
        if (userService.findUserById(getUser().getId()).getAuditStatus() == 2) {
            return new Result("success", Result.SUCCESS, "用户已实名认证通过，无法更新实名信息");
        }

        User user = new User();
        user.setId(getUser().getId());
        user.setStudentCardUrl(realNameDTO.getStudentCardUrl());
        user.setStudentCode(realNameDTO.getStudentCode());
        user.setRealName(realNameDTO.getRealName());
        user.setInstitute(realNameDTO.getInstitute());
        user.setProfessionalClass(realNameDTO.getProfessionalClass());
        userService.updateRealNameInfo(user);
        return new Result("success", Result.SUCCESS, "用户实名信息更新成功");
    }

    /**
     * 更新用户头像
     *
     * @param jsonObject
     * @return
     */
    @PostMapping("/updateHeader")
    public Result updateHeader(@RequestBody JSONObject jsonObject) {
        String headerUrl = jsonObject.getString("headerUrl");

        if (StringUtils.isEmpty(headerUrl)) {
            return new Result("fail", "1", "the request parameters are invalid");
        }

        int userId = getUser().getId();
        userService.updateHeader(userId, headerUrl);
        return new Result("success", Result.SUCCESS, "用户头像更新成功");
    }
}
